﻿using System;
using System.Collections.Generic;

namespace Loki.Commands
{
    /// <summary>
    /// Common interface for command manager service.
    /// </summary>
    public interface ICommandService
    {
        /// <summary>
        /// Creates and register a command handler fo the specified command.
        /// </summary>
        /// <param name="P_Command">The command.</param>
        /// <param name="P_CanExecute">The CanExecute function.</param>
        /// <param name="P_Execute">The Execute function.</param>
        /// <returns>You must hold a reference on the returned command handler as long as the listener observes the command.</returns>
        ICommandHandler CreateHandler(ICommand P_Command, Action<object, CanExecuteCommandEventArgs> P_CanExecute, Action<object, CommandEventArgs> P_Execute);

        ICommandHandler CreateHandler(ICommand P_Command, Action<object, CanExecuteCommandEventArgs> P_CanExecute, Action<object, CommandEventArgs> P_Execute, ICommandAware P_State);

        ICommandHandler CreateHandler(ICommand P_Command, Action<object, CanExecuteCommandEventArgs> P_CanExecute, Action<object, CommandEventArgs> P_Execute, ICommandAware P_State, Func<CommandEventArgs, bool> P_ConfirmDelegate);

        /// <summary>
        /// Adds the specified <see cref="ICommandHandler"/> for the specified command.
        /// </summary>
        /// <param name="P_Command">The command.</param>
        /// <param name="P_Handler">The command handler.</param>
        void AddHandler(ICommand P_Command, ICommandHandler P_Handler);

        /// <summary>
        /// Removes the specified <see cref="ICommandHandler"/> for the specified command.
        /// </summary>
        /// <param name="P_Command">The command.</param>
        /// <param name="P_Handler">The command handler.</param>
        void RemoveHandler(ICommand P_Command, ICommandHandler P_Handler);

        /// <summary>
        /// Registers a command.
        /// </summary>
        /// <param name="P_Command">The command.</param>
        void RegisterCommand(ICommand P_Command);

        /// <summary>
        /// Creates and registers a new command for the specified command name.
        /// </summary>
        /// <param name="P_CommandTag">Name of the command.</param>
        /// <returns>The registered command.</returns>
        ICommand CreateCommand(string P_CommandTag);

        /// <summary>
        /// Creates and registers an new command for the specified command name.
        /// </summary>
        /// <param name="P_IsDeepCommand">True if the command is deep.</param>
        /// <param name="P_CommandTag">Name of the command.</param>
        ICommand CreateCommand(bool P_IsDeepCommand, string P_CommandTag);

        /// <summary>
        /// Creates and registers a new command for the specified command name.
        /// </summary>
        ICommand CreateCommand();

        ICommand CreateCommand(bool P_IsDeepCommand);

        /// <summary>
        /// Unregister a command.
        /// </summary>
        /// <param name="P_Command">The command.</param>
        void UnregisterCommand(ICommand P_Command);

        /// <summary>
        /// Gets the handlers.
        /// </summary>
        /// <param name="P_Command">The command.</param>
        IEnumerable<ICommandHandler> GetHandlers(ICommand P_Command);
    }
}
